It is often desirable to be able to replicate the execution of a computer program in a manner such that the executing program exhibits, during replay, the same behavior that the program exhibited when the program originally executed. For example, a programmer might wish to record a program's behavior in a production environment and then replay that program in a debugging environment in order to locate and fix possible errors in the program code—errors that caused unexpected or undesirable results in the production environment. Under such circumstances, if the program behaves differently when replayed in the debugging environment than the program behaved in the production environment, the programmer may have great difficulty in isolating the source of the problems that were previously encountered.
Among the programs whose behavior it is desirable to replicate are programs that execute in a virtual machine environment. Such programs typically contain bytecode instructions that are interpreted at runtime and executed by a virtual machine that interfaces with the operating system of the physical hardware on which the virtual machine executes. The virtual machine is the entity that executes the machine language instructions in response to the interpretation of corresponding bytecode instructions. The JAVA programming language is an example of a programming language in which such programs may be written, although there are several programming languages that may be used to construct a program that executes in a virtual machine environment.
FIG. 1 illustrates an example of a virtual machine environment 100 in which a program may be executed. An application program 102 contains bytecode instructions that can be interpreted and executed by a virtual machine 104. Virtual machine 104 is capable of interpreting and executing a virtually infinite variety of different application programs, of which application program 102 is but one example. Application program 102 includes instructions that are selected and organized by one or more programmers with the intent of causing a computing device to operate in a specified manner; the choice of how the instructions are organized is up the programmers. Application program 102 may be written in JAVA source code before being compiled into the bytecode instructions that virtual machine 104 executes at run time. The JAVA virtual machine, or JVM, is an example of virtual machine 104. Although the instructions that make up the application programs that are executed by virtual machine 104 will vary from application program to application program, depending on the sets of operations whose performance is desired by the programmers of those application programs, virtual machine 104 remains constant.
Virtual machine 104 interfaces with operating system 106. In executing application program 102, virtual machine 104 makes calls into and receives return values from operating system 106. Typically, at least some functionality intended for application program 102 cannot be achieved by virtual machine 104 alone without the participation of operating system 106. The operations performed by virtual machine 104 itself while executing application program 102 will not vary from execution to execution; each time that virtual machine 104 executes application program 102, virtual machine 104 will perform exactly the same operations in response to the bytecode instructions of which application program 102 is made up. Therefore, the behavior of virtual machine 104 is said to be deterministic. Application program 102 is also deterministic in nature. However, virtual machine 104 has no control over the inner workings of operating system 106, and the timing with which operating system 106 responds to virtual machine 104 largely cannot be anticipated. Indeed, different versions of virtual machine 104 may be created to interface with different operating systems, and while the operations of each version of virtual machine 104 will remain consistent between versions (according to the specification of virtual machine 104), the different operating systems with which the different versions of virtual machine 104 interface may behave at least somewhat differently (e.g., in timing) from each other. Thus, the behavior of operating system 106 is non-deterministic. There is no inherent guarantee that operating system 106 will behave in exactly the same manner during separate executions of application program 102, despite the fact that application 102 and virtual machine 104 remain constant during those separate executions.
Theoretically, one might attempt to avoid the problems that arise from this non-determinism by not only recording the operations of application program 102, but also recording all of the operations of virtual machine 104 and operating system 106. Theoretically, one might attempt to simulate, during playback or “replay,” each and every operation that any element of environment 100, including virtual machine 104 and operating system 106, performed.
One problem that would likely arise from this theoretical approach pertains to the sheer size of the record that would be produced during recording. The quantity of details that would be recorded and later simulated during replay likely would be so voluminous that the record would occupy an inordinate amount of storage space and would consume inordinate computing resources during replay. The inefficiency produced by the overhead of simulating each and every detail of the operating system's original behavior would likely cause the replay of the application program to be magnitudes slower than the application program's original execution.
An even greater problem with this theoretical approach arises from the fact that no variance whatsoever from the original execution of the application program could be introduced where desired during replay. When each and every operation of the operating system and the virtual machine is replayed, then neither the virtual machine nor any other program is given the opportunity to cause some different behavior in the environment during replay. This inflexibility would make the debugging of the application program during replay a virtual impossibility. Usually, when an application program is being debugged in a virtual machine environment, the virtual machine itself needs to perform at least some operations that the virtual machine did not perform during the application program's original execution. For example, a virtual machine might need to halt (at least temporarily) the application program's execution at a user-specified moment and/or display the values of one or more variables at a user-specified moment so that the person debugging the application program can detect potential errors. Under some circumstances, only the virtual machine will be in a position to cause these temporal effects, and only the virtual machine will possess the information that a person debugging the application program would want to know. When all of the virtual machine's operations during replay are required to duplicate the virtual machine's operations exactly as they were observed during the application program's original execution, this requirement essentially prevents the virtual machine from acting in any sort of debugging capacity.
The approaches described in the section are approaches that could be pursued, but not necessarily approaches that have been previously conceived or pursued. Therefore, unless otherwise indicated, it should not be assumed that any of the approaches described in this section qualify as prior art merely by virtue of their inclusion in this section.